package main.leetcode.offer.firstround.from03to50;

/**
 * 39.数组中出现超过一半的数字
 *
 * <p>数组中有一个数字出现的次数超过数组长度的一半，请找出这个数字。
 *
 * <p>你可以假设数组是非空的，并且给定的数组总是存在多数元素。
 *
 * <p>
 *
 * <p>示例 1:输入: [1, 2, 3, 2, 2, 2, 5, 4, 2] 输出: 2
 *
 * <p>限制：1 <= 数组长度 <= 50000
 *
 * <p>来源：力扣（LeetCode）
 * 链接：https://leetcode-cn.com/problems/shu-zu-zhong-chu-xian-ci-shu-chao-guo-yi-ban-de-shu-zi-lcof
 * 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 */
public class ex39 {
    public static void main(String[] args) {
        System.out.println(new ex39().majorityElement(new int[] {1, 2, 3, 2, 2, 2, 5, 4, 2}));
    }

    //  public int majorityElement(int[] nums) {
    //    HashMap<Integer, Integer> map = new HashMap<>();
    //    int n = nums.length;
    //    int time;
    //    for (int num : nums) {
    //      if (map.containsKey(num)) {
    //        time = map.get(num);
    //        if (time >= n / 2) return num;
    //        map.put(num, map.get(num) + 1);
    //      } else map.put(num, 1);
    //    }
    //    return nums[n - 1];
    //  }

    // Boyer-Moore 投票算法
    // 如果遇到一个我们目前的候选众数，就将计数器加一，否则减一。只要计数器等于 0 ，我们就将 nums 中之前访问的数字全部 忘记 ，并把下一个数字当做候选的众数。
    public int majorityElement(int[] nums) {
        int count = 1; // 计数器
        int candidate = nums[0]; // 候选人
        for (int i = 1; i < nums.length; i++) {
            if (count == 0) candidate = nums[i];
            if (nums[i] == candidate) count++;
            else count--;
        }
        return candidate;
    }
}
